package jp.co.sega.sonic_jump.monthly.sum;

import android.graphics.Bitmap;
import android.graphics.Rect;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;

public class BitmapFont {

    /*public final Bitmap bitmapFontImage1;
    public final Bitmap bitmapFontImage2;
    public final String charMap1;
    public final String charMap2;
    public final int charWidth;
    public final int charHeight;
    public final int columns;*/
    private final List<BitmapEntry> bitmapEntries;
    public static boolean advancemap;
    public final Map<Character, Integer> ADVANCE_MAP;
    public static boolean bignum = false;
    
    // Mapeamento: caractere composto → (base, diacrítico)
    public static final Map<Character, Pair<Character, Character>> COMPOSED_MAP;

    static {
        Map<Character, Pair<Character, Character>> map = new HashMap<>();
        /*map.put('Á', new Pair<>('A', '´'));
        map.put('À', new Pair<>('A', '`'));
        map.put('Â', new Pair<>('A', '^'));
        map.put('Ã', new Pair<>('A', '~'));
        map.put('É', new Pair<>('E', '´'));
        map.put('Ê', new Pair<>('E', '^'));
        map.put('Í', new Pair<>('I', '´'));
        map.put('Ó', new Pair<>('O', '´'));
        map.put('Ô', new Pair<>('O', '^'));
        map.put('Õ', new Pair<>('O', '~'));
        map.put('Ú', new Pair<>('U', '´'));
        map.put('Ñ', new Pair<>('N', '~'));*/
        //map.put('ñ', new Pair<>('n', '~'));
        COMPOSED_MAP = Collections.unmodifiableMap(map);
    }

    /*public BitmapFont(Bitmap bitmapFontImage1, Bitmap bitmapFontImage2, int charWidth, int charHeight, int columns, String charMap1, String charMap2) {
    this.bitmapFontImage1 = bitmapFontImage1;
    this.charMap1 = charMap1;
    this.bitmapFontImage2 = bitmapFontImage2;
    this.charMap2 = charMap2;
    this.charWidth = charWidth;
    this.charHeight = charHeight;
    this.columns = columns;
}*/
    
    public static class BitmapEntry {
    public final Bitmap bitmap;
    public final String charMap;
    public final int charWidth;
    public final int charHeight;
    public final int columns;

    public BitmapEntry(Bitmap bitmap, String charMap, int charWidth, int charHeight, int columns) {
        this.bitmap = bitmap;
        this.charMap = charMap;
        this.charWidth = charWidth;
        this.charHeight = charHeight;
        this.columns = columns;
    }
    
    public static BitmapEntry getBitmapEntryForChar(BitmapFont bitmapFont, char c) {
    Bitmap desiredBitmap = null;
    
    if (Graphics.bignum && (c == '¡' || c == ':' || c == '!' || Character.isDigit(c))) {
        desiredBitmap = Shell.sInstance.getCanvas().G.getB6();
    }

    for (BitmapEntry entry : bitmapFont.bitmapEntries) {
        if (entry.charMap.indexOf(c) != -1) {
            if (desiredBitmap != null) {
                if (entry.bitmap == desiredBitmap) {
                    return entry;
                } else {
                    continue;
                }
            } else {
                return entry;
            }
        }
    }
    return null;
}
}

public BitmapFont(List<BitmapEntry> bitmapEntries, boolean advancemap) {
    this.bitmapEntries = bitmapEntries;
    this.advancemap = advancemap;
    
    Map<Character, Integer> map = new HashMap<>();

    // Letras estreitas
    if (advancemap) {
    map.put('I', 10);
    map.put('P', 17);
    map.put('Q', 18);
    }
    /*map.put('i', 30);
    map.put('l', 30);
    map.put('I', 31);
    map.put('t', 31);
    map.put('f', 31);
    map.put('j', 30);
    map.put('r', 31);

    // Letras largas
    map.put('m', 37);
    map.put('w', 37);
    map.put('W', 39);
    map.put('M', 38);

    // Pontuação estreita
    map.put('.', 27);
    map.put(',', 27);
    map.put(':', 27);
    map.put(';', 27);
    map.put('!', 27);
    map.put('?', 30);
    map.put('-', 27);
    map.put('\'', 25);
    map.put('"', 28);*/

    ADVANCE_MAP = Collections.unmodifiableMap(map);
}

    // Estrutura de retorno para renderização
    public static class CharInfo {
    public final CharRect base;
    public final CharRect diacritic;
    public final int OffsetX;
    public final int OffsetY;
    public final int advanceWidth;

    public CharInfo(CharRect base, CharRect diacritic, int OffsetX, int OffsetY, int advanceWidth) {
        this.base = base;
        this.diacritic = diacritic;
        this.OffsetX = OffsetX;
        this.OffsetY = OffsetY;
        this.advanceWidth = advanceWidth;
    }
}
    
    public static class Pair<F, S> {
    public final F first;
    public final S second;

    public Pair(F first, S second) {
        this.first = first;
        this.second = second;
    }
}

    /**
     * Retorna retângulos do caractere base e diacrítico, se houver.
     */

    public CharInfo getCharInfo(char c) {
    if (c == ' ' || c == '\n') {
        BitmapEntry entry = bitmapEntries.isEmpty() ? null : bitmapEntries.get(0);
        int advance = ADVANCE_MAP.getOrDefault(c, entry != null ? entry.charWidth / 2 : 10);
        return new CharInfo(null, null, 0, 0, advance);
    }

    Pair<Character, Character> composed = COMPOSED_MAP.get(c);
    if (composed == null) {
        CharRect single = getCharRect(c);
        if (single == null) {
            if (Character.isLowerCase(c)) {
                char upper = Character.toUpperCase(c);
                CharRect upperRect = getCharRect(upper);
                if (upperRect == null) return null;
                Rect adjusted = new Rect(
                    upperRect.rect.left,
                    upperRect.rect.top/* + 8*/,
                    upperRect.rect.right/* - 2*/,
                    upperRect.rect.bottom
                );
                CharRect adjustedRect = new CharRect(upperRect.bitmap, adjusted, upperRect.entry);
                BitmapEntry entry = upperRect.entry;//getBitmapEntryForChar(upper);
                int advance = ADVANCE_MAP.getOrDefault(c, entry != null ? entry.charWidth : 10);
                return new CharInfo(adjustedRect, null, 0, 0, advance);
            }
            return null;
        }
        BitmapEntry entry = single.entry;//getBitmapEntryForChar(c);
        int advance = ADVANCE_MAP.getOrDefault(c, entry != null ? entry.charWidth : 10);
        int offsetY = 0;
        if (raiseCharacters().contains(String.valueOf(c))) {
           offsetY = Game_Draw.BigFont ? -6 : -5;
        }
        return new CharInfo(single, null, 0, offsetY, advance);
    } else {
    CharRect base = null;
    /*if (Character.isLowerCase(composed.first)) {
    char upper = Character.toUpperCase(composed.first);
    CharRect upperRect = getCharRect(upper);
    if (upperRect == null) return null;
    Rect adjusted = new Rect(upperRect.rect.left, upperRect.rect.top + 8, upperRect.rect.right - 2, upperRect.rect.bottom);
    base = new CharRect(upperRect.bitmap, adjusted);
    } else {*/
        base = getCharRect(composed.first);
        //}
        CharRect diacritic = getCharRect(composed.second);
        BitmapEntry entry = getBitmapEntryForChar(c);
        if (base == null || diacritic == null) return null;
        int offsetX = (c == '"') ? 4 : 0;
        int offsetY = (c == '"') ? 0 : -entry.charHeight / 2;
        BitmapEntry entry2 = getBitmapEntryForChar(composed.first);
        int advance = ADVANCE_MAP.getOrDefault(composed.first, entry != null ? entry2.charWidth : 10);
        return new CharInfo(base, diacritic, offsetX, offsetY, advance);
    }
}

    public String raiseCharacters() {
    return "ÁÀÄÂÃÉÈËÊẼÓÒÖÔÕÚÙÜÛŨÑÍÌáàäâãéèëêẽóòöôõúùüûũñíì";
    }

    /**
     * Calcula a posição do caractere no bitmap.
     */
     
    public static class CharRect {
    public final Bitmap bitmap;
    public final Rect rect;
    public final BitmapEntry entry;

    public CharRect(Bitmap bitmap, Rect rect, BitmapEntry entry) {
        this.bitmap = bitmap;
        this.rect = rect;
        this.entry = entry;
    }
}
    /*public CharRect getCharRect(char c) {
    int index = charMap1.indexOf(c);
    if (index != -1) {
        int row = index / columns;
        int col = index % columns;
        Rect rect = new Rect(
            col * charWidth,
            row * charHeight,
            (col + 1) * charWidth,
            (row + 1) * charHeight
        );
        return new CharRect(bitmapFontImage1, rect);
    }

    index = charMap2.indexOf(c);
    if (index != -1) {
        int row = index / columns;
        int col = index % columns;
        Rect rect = new Rect(
            col * charWidth,
            row * charHeight,
            (col + 1) * charWidth,
            (row + 1) * charHeight
        );
        return new CharRect(bitmapFontImage2, rect);
    }

    return null; // Não encontrado
}*/
    public CharRect getCharRect(char c) {
    Bitmap desiredBitmap = null;
    
    if (Graphics.bignum && (c == '¡' || c == ':' || c == '!' || Character.isDigit(c))) {
        desiredBitmap = Shell.sInstance.getCanvas().G.getB6();
    }
    for (BitmapEntry entry : bitmapEntries) {
        int index = entry.charMap.indexOf(c);
        if (index != -1) {
            if (desiredBitmap != null) {
                if (entry.bitmap != desiredBitmap) {
                    continue;
                }
            }
            //int columns = entry.bitmap.getWidth() / entry.charWidth;
            int columns = entry.columns;
            int row = index / columns;
            int col = index % columns;
            Rect rect = new Rect(
                col * entry.charWidth,
                row * entry.charHeight,
                (col + 1) * entry.charWidth,
                (row + 1) * entry.charHeight
            );
            return new CharRect(entry.bitmap, rect, entry);
        }
    }
    return null;
}
    /**
     * Retorna a imagem do bitmap inteiro (se precisar para seu renderer).
     */

    private BitmapEntry getBitmapEntryForChar(char c) {
    for (BitmapEntry entry : bitmapEntries) {
        if (entry.charMap.indexOf(c) != -1) {
            return entry;
        }
    }
    return null;
}
}